home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C -*- */
- /* EditCard.cc - Edit an existing card
- * Created by Robert Heller on Wed Dec 11 20:41:43 1991
- *
- * ------------------------------------------------------------------
- * Home Libarian by Deepwoods Software
- * Edit a Librarian Card Catalog file
- * ------------------------------------------------------------------
- * Modification History:
- * ------------------------------------------------------------------
- * Contents:
- * ------------------------------------------------------------------
- *
- *
- * Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
- * All Rights Reserved
- *
- */
-
- #include <stream.h>
- #include <vBTree.h>
- #include <ctype.h>
- #ifdef MESSYDOS
- #include <CardRec.h>
- #include <ListRec.h>
- #else
- #include <CardRecord.h>
- #include <ListRecord.h>
- #endif
- #include <Terminal.h>
- #ifdef MESSYDOS
- #include <CmdScren.h>
- #else
- #include <CommandScreen.h>
- #endif
- #include <EditForm.h>
- #include "EditDefs.h"
- #include "EditGlob.h"
-
-
- const BuffSize = 1024;
- const DescrSize = 4096;
- static Key editkey;
- static char Author[BuffSize],Title[BuffSize],Publisher[BuffSize],
- City[BuffSize],Description[DescrSize],SubjList[DescrSize],
- OrigSubjList[DescrSize];
- static Card editcard(Book,Author,Title,Publisher,City,Description,0,0);
-
- static char* TypeToString(void* f) {CardType ct = *((CardType*)f);return(TypeName(ct));}
- static void StringToType(char* s,void* f){*((CardType*)f) = NameType(s);}
- static Card* OrigCard;
-
-
- static Boolean streqp(const char* s1,const char* s2)
- {
- register char c1,c2;
- do {
- c1 = *s1++;
- if (islower(c1)) c1 = toupper(c1);
- c2 = *s2++;
- if (islower(c2)) c2 = toupper(c2);
- if (c1 != c2) return(false);
- } while (c1 != 0);
- return(true);
- }
-
- static char* ReadQuotedStringFromBuffer(char* buffer,int buffsize,char* string)
- {
- Boolean inquote = false;
-
- if (string == 0 || *string == 0) return((char*)0);
- while (*string != 0 && (inquote || *string != ',')) {
- if (*string == '"') inquote = ~inquote;
- else if (*string == '\\') {
- string++;
- if (buffsize > 0) {
- *buffer++ = *string;
- buffsize--;
- }
- } else if (*string >= ' ') {
- if (buffsize > 0) {
- *buffer++ = *string;
- buffsize--;
- }
- }
- string++;
- }
- if (*string == ',') string++;
- *buffer = 0;
- return string;
- }
-
- static char* newelems[500];
- void UpdateSubjs(const char* subjs,const char* osubjs,const Key key)
- {
- Key subj1;
- Key subj2;
- char* sl1;
- char* sl2;
-
- for (sl1 = (char*)osubjs;(sl1 = ReadQuotedStringFromBuffer((char*)subj1,sizeof(subj1),sl1)) != 0;) {
- Boolean retain = false;
- for (sl2 = (char*)subjs;(sl2 = ReadQuotedStringFromBuffer((char*)subj2,sizeof(subj2),sl2)) != 0;) {
- if (streqp(subj2,subj1)) {
- retain = true;
- break;
- }
- }
- if (!retain) {
- CoreItem temp;
- if (Tree->SearchSubj(subj1,&temp)) {
- ListRecord rec(&temp.data);
- int nitems = rec.ElementCount();
- int outitems = 0;
- for (int i = 0; i < nitems; i++) {
- if (!streqp(rec[i],key)) {
- newelems[outitems++] = rec[i];
- }
- }
- if (outitems == 0) Tree->DeleteSubj(subj1);
- else {
- ListRecord newrec(outitems,newelems);
- Record rawrec = newrec;
- Tree->InsertSubj(subj1,&rawrec);
- }
- }
- }
- }
- for (sl1 = (char*)subjs;(sl1 = ReadQuotedStringFromBuffer((char*)subj1,sizeof(subj1),sl1)) != 0;) {
- Boolean addnew = true;
- for (sl2 = (char*)osubjs;(sl2 = ReadQuotedStringFromBuffer((char*)subj2,sizeof(subj2),sl2)) != 0;) {
- if (streqp(subj2,subj1)) {
- addnew = false;
- break;
- }
- }
- if (addnew) {
- CoreItem temp;
- if (Tree->SearchSubj(subj1,&temp)) {
- ListRecord rec(&temp.data);
- int nitems = rec.ElementCount();
- int outitems = 0;
- for (int i = 0; i < nitems; i++) {
- if (!streqp(rec[i],key)) {
- newelems[outitems++] = rec[i];
- }
- }
- newelems[outitems++] = (char*)key;
- ListRecord newrec(outitems,newelems);
- Record rawrec = newrec;
- Tree->InsertSubj(subj1,&rawrec);
- } else {
- newelems[0] = (char*)key;
- ListRecord newrec(1,newelems);
- Record rawrec = newrec;
- Tree->InsertSubj(subj1,&rawrec);
- }
- }
- }
- }
-
- void UpdateAuthor(const char* auth,const char* oauth,const Key key)
- {
- Key authkey;
- Key oauthkey;
- strncpy(authkey,auth,KeySize);
- authkey[KeySize-1] = 0;
- strncpy(oauthkey,oauth,KeySize);
- oauthkey[KeySize-1] = 0;
- //cerr << "*** In UpdateAuthor: authkey = '" << authkey << "', oauthkey = '" << oauthkey << "'\n";
- if (!streqp(authkey,oauthkey)) {
- CoreItem temp;
- //cerr << "Author changed, about to update old author\n";
- if (Tree->SearchAuthor(oauthkey,&temp) &&
- streqp(oauthkey,temp.key)) {
- //cerr << "Updating old author...\n";
- ListRecord rec(&temp.data);
- int nitems = rec.ElementCount();
- int outitems = 0;
- for (int i = 0; i < nitems; i++) {
- if (!streqp(rec[i],key)) {
- newelems[outitems++] = rec[i];
- }
- }
- if (outitems == 0) Tree->DeleteAuthor(oauthkey);
- else {
- ListRecord newrec(outitems,newelems);
- Record rawrec = newrec;
- Tree->InsertAuthor(oauthkey,&rawrec);
- }
- //cerr << "Old author updated...\n";
- }
- //cerr << "About to fetch new author record\n";
- if (Tree->SearchAuthor(authkey,&temp) &&
- streqp(authkey,temp.key)) {
- //cerr << "New author record fetched, about to update\n";
- ListRecord rec(&temp.data);
- int nitems = rec.ElementCount();
- int outitems = 0;
- for (int i = 0; i < nitems; i++) {
- if (!streqp(rec[i],key)) {
- newelems[outitems++] = rec[i];
- }
- }
- newelems[outitems++] = (char*)key;
- ListRecord newrec(outitems,newelems);
- Record rawrec = newrec;
- //cerr << "Inserting new record for new author...\n";
- Tree->InsertAuthor(authkey,&rawrec);
- } else if (authkey[0] != 0) {
- //cerr << "Creating new record for new author...\n";
- newelems[0] = (char*)key;
- ListRecord newrec(1,newelems);
- Record rawrec = newrec;
- Tree->InsertAuthor(authkey,&rawrec);
- }
- }
- }
-
- void UpdateTitle(const char* title,const char* otitle,const Key key)
- {
- Key titlekey;
- Key otitlekey;
- strncpy(titlekey,title,KeySize);
- titlekey[KeySize-1] = 0;
- strncpy(otitlekey,otitle,KeySize);
- otitlekey[KeySize-1] = 0;
- //cerr << "*** In UpdateTitle: titlekey = '" << titlekey << "', otitlekey = '" << otitlekey << "'\n";
- if (!streqp(titlekey,otitlekey)) {
- CoreItem temp;
- if (Tree->SearchTitle(otitlekey,&temp) &&
- streqp(otitlekey,temp.key)) {
- ListRecord rec(&temp.data);
- int nitems = rec.ElementCount();
- int outitems = 0;
- for (int i = 0; i < nitems; i++) {
- if (!streqp(rec[i],key)) {
- newelems[outitems++] = rec[i];
- }
- }
- if (outitems == 0) Tree->DeleteTitle(otitlekey);
- else {
- ListRecord newrec(outitems,newelems);
- Record rawrec = newrec;
- Tree->InsertTitle(otitlekey,&rawrec);
- }
- }
- if (Tree->SearchTitle(titlekey,&temp) &&
- streqp(titlekey,temp.key)) {
- ListRecord rec(&temp.data);
- int nitems = rec.ElementCount();
- int outitems = 0;
- for (int i = 0; i < nitems; i++) {
- if (!streqp(rec[i],key)) {
- newelems[outitems++] = rec[i];
- }
- }
- newelems[outitems++] = (char*)key;
- ListRecord newrec(outitems,newelems);
- Record rawrec = newrec;
- Tree->InsertTitle(titlekey,&rawrec);
- } else if (titlekey[0] != 0) {
- newelems[0] = (char*)key;
- ListRecord newrec(1,newelems);
- Record rawrec = newrec;
- Tree->InsertTitle(titlekey,&rawrec);
- }
- }
- }
-
- void QuoteStringBuffer(char* buffer,char* string)
- {
- *buffer++ = '"';
- while (*string != 0) {
- if (*string == '"') *buffer++ = '\\';
- *buffer++ = *string++;
- }
- *buffer++ = '"';
- *buffer = 0;
- }
-
- static char *ptr;
- static Key subjkey;
- static void ExamineSubj(CoreItem* item,int level)
- {
- if (item->data.size <= 0) return;
- ListRecord rec(&item->data);
- int icount = rec.ElementCount();
- for (int i = 0; i < icount; i++) {
- if (streqp(subjkey,rec[i])) {
- QuoteStringBuffer(ptr,item->key);
- ptr += strlen(ptr);
- *ptr++ = ',';
- return;
- }
- }
- }
-
- void FetchSubjs(char* subjbuffer,const Key key)
- {
- ptr = subjbuffer;
- strcpy(subjkey,key);
- Tree->TraverseSubj(ExamineSubj);
- if (ptr > subjbuffer && *(ptr-1) == ',') ptr--;
- *ptr = '\0';
- }
-
- Boolean CardsAreDifferent(const Card *c1,const Card *c2)
- {
- if (c1->type != c2->type ||
- c1->vol != c2->vol ||
- c1->year != c2->year ||
- strcmp(c1->author,c2->author) != 0 ||
- strcmp(c1->title,c2->title) != 0 ||
- strcmp(c1->publisher,c2->publisher) != 0 ||
- strcmp(c1->city,c2->city) != 0 ||
- strcmp(c1->description,c2->description) != 0) return(true);
- else return(false);
- }
-
- static void SaveCard(EditForm& ef)
- {
- if (OrigCard != 0 && CardsAreDifferent(&editcard,OrigCard)) {
- CardRecord rec(&editcard);
- Record rawrec = rec;
- Tree->InsertId(editkey,&rawrec);
- UpdateAuthor(Author,OrigCard->author,editkey);
- UpdateTitle(Title,OrigCard->title,editkey);
- } else {
- CardRecord rec(&editcard);
- Record rawrec = rec;
- Tree->InsertId(editkey,&rawrec);
- UpdateAuthor(Author,"",editkey);
- UpdateTitle(Title,"",editkey);
- }
- UpdateSubjs(SubjList,OrigSubjList,editkey);
- strcpy(OrigSubjList,SubjList);
- Term->Message("Saved");
- ef.IsModified = false;
- return;
- }
-
- static Field Fields[] = {
- {"Id: ",Literal,0,0,3,1,4,1,0},
- {editkey,Literal,0,0,3,5,KeySize,1,0},
- {"Type: ",Literal,0,0,3,50,6,1,0},
- {&editcard.type,Special,TypeToString,StringToType,3,56,14,1,0},
- {"Title: ",Literal,0,0,4,1,7,1,0},
- {Title,String,0,0,4,8,60,1,BuffSize},
- {"Author: ",Literal,0,0,5,1,8,1,0},
- {Author,String,0,0,5,9,60,1,BuffSize},
- {"Publisher: ",Literal,0,0,6,1,11,1,0},
- {Publisher,String,0,0,6,12,40,1,BuffSize},
- {"Year: ",Literal,0,0,6,60,6,1,0},
- {&editcard.year,Int,0,0,6,66,4,1,0},
- {"City: ",Literal,0,0,7,1,6,1,0},
- {City,String,0,0,7,7,40,1,BuffSize},
- {"Vol: ",Literal,0,0,7,60,5,1,0},
- {&editcard.vol,Int,0,0,7,65,4,1,0},
- {"Description: ",Literal,0,0,8,1,13,1,0},
- {Description,EditorString,0,0,8,14,50,10,DescrSize},
- {"Subjects: ",Literal,0,0,19,1,10,1,0},
- {SubjList,EditorString,0,0,19,11,50,3,DescrSize}
- };
-
- static const NumFields = sizeof(Fields) / sizeof(Field);
-
- static void HelpField(EditForm& ef)
- {
- switch (ef.CurField()) {
- case 4: // Type:
- Term->Clear();
- Term->PutStrAt(2,0,"Type field - enter one of:");
- Term->PutStrAt(4,0,"Book, Magazine, CD, AudioCassette, Album, LaserDisk, VHSVideo,");
- Term->PutStrAt(5,0,"BetaVideo, EightMM, EightTrack, DAT, or Other.");
- Term->PutStrAt(7,0,"This is the type of item being cataloged.");
- Term->PutStrAt(0,0,"Hit any key to resume editing:");
- Term->GetKey();
- ef.RePaint();
- break;
- case 6: // Title: (string)
- Term->Message("Title field - enter the title as a string");
- break;
- case 8: // Author: (string)
- Term->Message("Author field - enter the author as a string");
- break;
- case 10: // Publisher: (string)
- Term->Message("Publisher field - enter the publisher as a string");
- break;
- case 12: // Year: (number)
- Term->Message("Year field - enter the year as a number");
- break;
- case 14: // City: (string)
- Term->Message("City field - enter the city as a string");
- break;
- case 16: // Volume: (number)
- Term->Message("Volumn field - enter the volume number as a number");
- break;
- case 18: // Description (long string)
- Term->Message("Description field - enter the description as a multi-line string");
- break;
- case 20: // Subjects (long string)
- Term->Message("Subjects field - enter the subjects as a comma separated list of strings");
- break;
- }
- }
-
- static KeyBinding Bindings[] = {
- {SaveCard,"^S - Save card",'S' - '@'},
- {HelpField,"H - Give help for the current field",'H'},
- {HelpField,"h - Give help for the current field",'h'}
- };
- static const NumBindings = sizeof(Bindings) / sizeof(KeyBinding);
-
- int EditCard1(Key inkey)
- {
- #ifdef ILLEGAL_INSTR
- static EditForm editform("Editing a Card",NumFields,Fields,
- NumBindings,Bindings);
- #else
- EditForm *editform = new EditForm("Editing a Card",NumFields,Fields,
- NumBindings,Bindings);
- #endif
-
- strcpy(editkey,inkey);
- CoreItem item;
- #ifdef ILLEGAL_INSTR
- editform.ResetField();
- #else
- editform->ResetField();
- #endif
- if (Tree->SearchId(editkey,&item) &&
- strlen(editkey) == strlen(item.key)) {
- strcpy(editkey,item.key);
- CardRecord crec(&item.data);
- strcpy(Author,crec->author);
- strcpy(Title,crec->title);
- strcpy(Publisher,crec->publisher);
- strcpy(City,crec->city);
- strcpy(Description,crec->description);
- editcard.year = crec->year;
- editcard.vol = crec->vol;
- editcard.type = crec->type;
- FetchSubjs(SubjList,editkey);
- strcpy(OrigSubjList,SubjList);
- OrigCard = &crec;
- #ifdef ILLEGAL_INSTR
- if(editform.RunForm()) {
- #else
- if(editform->RunForm()) {
- #endif
- if (Term->YorNp(20,0,"Card modified - save it?"))
- #ifdef ILLEGAL_INSTR
- SaveCard(editform);
- #else
- SaveCard(*editform);
- #endif
- }
- } else if (Term->YorNp(21,0,"Card not found, create it?")) {
- Author[0] = 0;
- Title[0] = 0;
- Publisher[0] = 0;
- City[0] = 0;
- Description[0] = 0;
- SubjList[0] = 0;
- OrigSubjList[0] = 0;
- OrigCard = 0;
- editcard.type = Book;
- editcard.vol = 0;
- editcard.year = 0;
- #ifdef ILLEGAL_INSTR
- if(editform.RunForm()) {
- #else
- if(editform->RunForm()) {
- #endif
- if (Term->YorNp(20,0,"Card modified - save it?"))
- #ifdef ILLEGAL_INSTR
- SaveCard(editform);
- #else
- SaveCard(*editform);
- #endif
- }
- }
- #ifndef ILLEGAL_INSTR
- delete editform;
- #endif
- return(-1);
- }
-
-
- int EditCard()
- {
- static Key tempkey;
-
- Term->PromptLine(18,0,"Id of card to edit: ",tempkey,KeySize);
- return(EditCard1(tempkey));
- }
-
-